/*

战场布置：
campaign + forceinfo + direction -> UI

玩家操作：
UI + manipulate -> direction
AI操作：
campaign + forceinfo + direction + AI -> direction

回合计算：
campaign + forceinfo + direction -> process

回合核算：
campaign + process -> campaign
forceinfo + process -> forceinfo


p : process
d : direction
-> : generate/new/modify
== : skip

[单机]玩家回合：		布置界面操作(p/d->d)		==			核算(p/d->p/d)		==			显示动画(p->a)
[单机]AI回合：		AI生成指令(p/d->d)		==			核算(p/d->p/d)		==			显示动画(p->a)


[主机]本机回合：		布置界面操作(p/d->d)		==			核算(p/d->p/d)		发送	(p/d->)	显示动画(p->a)
[客机]他机回合：		==						==			==					接收(->p/d)	显示动画(p->a)


[客机]本机回合：		布置界面操作(p/d->d)		发送(d->)	==					接收(->p/d)	显示动画(p->a)
[主机]他机回合：		==						接收(->d)	核算(p/d->p/d)		发送(p/d->)	显示动画(p->a)


[主机]AI回合：		AI生成指令(p/d->d)		==			核算(p/d->p/d)		发送	(p/d->)	显示动画(p->a)
[客机]AI回合：		==						==			==					接收(->p/d)	显示动画(p->a)


客户端属性：[单机]/[主机]/[客机]
各玩家属性：AI/主机/客机/
消息类型：客机发给主机的d，主机发给客机的p/d，发给对方的消息和请求（停战等）


各种判别：
campaignRoom.isHost 本机是否主机，单机也看做主机
campaignRoom.isOnline 是否联线对战
gameUserEngine.isLocalPlayer(userid) 该玩家是否本地单机玩家
gameUserEngine.isOnlinePlayer(userid) 该玩家是否联线对战玩家
gameUserEngine.isAI(userid) 该玩家是否AI玩家
*/



//可用/禁用  所有按钮和点击操作
var SetAllManipulateEnable = function(enable){
	control.menuBackMenu.enabled = enable;
	control.warInfoMenu.enabled = enable;
	control.battleReviewMenu.enabled = enable;
	control.deployMenu.enabled = enable;
	battleLayerClickEnable = enable;
	directionMenu.SetAllMenuEnable(enable);
	courtDirectionMenu.SetAllMenuEnable(enable);
	if (enable == false)
		tipPanel.HideUI();
};

//卸载操作环境
var UnLoadManipulateEnvironment = function(){
	UnLoadDirections();
	SetAllManipulateEnable(false);
	control.warInfoMenu.enabled = true;
};

//结束回合
var onOldStepEnd = [];
var EndOldStep = function(){
	for (var idx in onOldStepEnd)
		onOldStepEnd[idx]();
};

//模拟 judgeBattle.Judge
var SimulateJudge = function(){
	for (var idx = 0; idx < wholeProcess[campaign.time_ref.current_step].length; idx++){
		var data = wholeProcess[campaign.time_ref.current_step][idx];
		processCursor[data.type].Modify(data);
	}
};

var showingForce = 0;

//获取下一个要展示的玩家，并作为当前展示玩家 ----------------------------------------------------
var TurnShowingForce = function(){
	var newShowingForce = campaign.time_ref.force_of_step;
	var _iniForce = newShowingForce;
	while (true){
		if (campaignRoom.isOnline == false){
			if (gameUserEngine.isLocalPlayer(campaignRoom.users[newShowingForce].id))
				break;
		}else{
			if (campaignRoom.users[newShowingForce].commonId == userSet.user.id)
				break;
		}

		newShowingForce = (newShowingForce + 1) % campaign.force.length;
		if (newShowingForce == _iniForce){
			cc.log("Error : showingForce not found!");
			break;
		}
	}
	showingForce = newShowingForce;
};

//开始新回合，仅日期/势力转换
var TurnNewStep = function(){
	campaignTimeEngine.BuildNewTime(campaign.time_ref);
	campaignTimeEngine.TurnForce(campaign.time_ref, campaign.force.length);	
};

//新回合要做的事
var onNewStepStart = [];
var StartNewStep = function(){
	for (var idx in onNewStepStart)
		onNewStepStart[idx]();
};

//加载操作环境
var LoadManipulateEnvironment = function(){
	LoadDirections();
	SetAllManipulateEnable(true);
};

//网络收发数据
var gameNetService = {
	//发送数据
	_lastGetTime : 0,
	SendGameData : function(userid, type, step, message, direction, process){		
		var gameData = gameDataEngine.CreateGameData(campaignRoom.id, userid,
				type, step, message, direction, process);
		netService.BuildData(userSet.user.id, JSON.stringify(gameData), gameNetService._SendGameDataHandler, 9);
	},

	_SendGameDataHandler : function(text){
		//cc.log("send data recieved : " + text);
		if (text == null){
			var winSize = cc.director.getWinSize();
			messageBox.Show("发送游戏数据失败!请检查网络设置", campaignScene.battlelayer,
				0.5 * winSize.width, 0.5 * winSize.height);
			return;
		}
		var dataid = parseInt(text);
		if (dataid == null || isNaN(dataid) || dataid < 0){
			messageBox.Show("发送游戏数据异常!请联系游戏管理员", campaignScene.battlelayer,
				0.5 * winSize.width, 0.5 * winSize.height);
			return;
		}
	},
	
	//接收数据
	_getGameDataHandler : null,
	_getGameDataUserid : 0,
	_getGameDataType : 0,
	_getGameDataIntervalHandle : null,
	GetGameData : function(userid, type, handler){	
		gameNetService._getGameDataUserid = userid,
		gameNetService._getGameDataType = type;
		gameNetService._getGameDataHandler = handler;
		gameNetService.StopGetGameData();
		gameNetService._getGameDataIntervalHandle = setInterval( gameNetService._GetGameData, 5.5 * 1000);
	},
	_GetGameData : function(){
		netService.GetData(userSet.user.id, campaignRoom.id, gameNetService._getGameDataUserid,
				gameNetService._getGameDataType, gameNetService._lastGetTime, gameNetService._ReceiveGameDataHandler, 1);
	},
	_ReceiveGameDataHandler : function(text){
		if (text == null){
			return;
		}
		if (text[0] != '{' || text[text.length - 1] != '}'){
			return;
		}
		var gamedata = JSON.parse(text);
		if (gamedata == null){
			var winSize = cc.director.getWinSize();
			messageBox.Show("接收游戏数据异常!() 请联系游戏管理员", campaignScene.battlelayer,
					0.5 * winSize.width, 0.5 * winSize.height);
			return;
		}
		
		gamedata.param = JSON.parse(gamedata.param);
		if (gamedata.param == null){
			var winSize = cc.director.getWinSize();
			messageBox.Show("接收游戏数据异常!() 请联系游戏管理员", campaignScene.battlelayer,
					0.5 * winSize.width, 0.5 * winSize.height);
			return;
		}
		
		gameNetService._lastGetTime = gamedata.time;
		
		if (gamedata.type == 0){
			gameBroadcastChannel.HandleGameData(gamedata);
		}
		else{
			gameNetService._getGameDataHandler(gamedata);
		}
		
	},
	StopGetGameData : function(){
		if (gameNetService._getGameDataIntervalHandle != null){
			clearInterval(gameNetService._getGameDataIntervalHandle);
			gameNetService._getGameDataIntervalHandle = null;
		}
	}
};

var gameLoop = {
	
	_step : 0,
	
	_commonid : null,
	
	_userid : null,
	
	_loopTimeoutHandle : null,
	
	StopGameLoop : function(){
		if (gameLoop._loopTimeoutHandle != null){
			clearTimeout(gameLoop._loopTimeoutHandle);
			gameLoop._loopTimeoutHandle = null;
		}
	},
	
	//布置场景 ----------------------------------------------------
	StartStep : function(){
		gameLoop._step = campaign.time_ref.current_step;
		var forceid = campaign.time_ref.force_of_step;
		gameLoop._userid = campaignRoom.users[forceid].id;
		gameLoop._commonid = campaignRoom.users[forceid].commonId;
		
		cc.log(gameLoop._step + ".1: stepStart start");
		StartNewStep();
		gameLoop._loopTimeoutHandle = setTimeout(
				gameLoop.LoadManipulate, campaignScene.canvaslayer.hideDuration * 1000);

	},
	
	//载入操作环境 ----------------------------------------------------
	LoadManipulate : function(){
		cc.log(gameLoop._step + ".2: stepStart end, new direction start");
		
		LoadManipulateEnvironment();
		
		if (gameUserEngine.isLocalPlayer(gameLoop._userid)
				|| ( gameUserEngine.isOnlinePlayer(gameLoop._userid)
						&& gameLoop._commonid == userSet.user.id) ){
			//允许操作 : [单机]玩家回合  or [主机]本机回合  or [客机]本机回合
			manipulateEnable = true;
		}
		else if ( campaignRoom.isHost && gameUserEngine.isAI(gameLoop._userid)){
			//计算AI指令 : [单机/主机] AI回合
			//TODO:计算AI指令
			manipulateEnable = false;
			gameLoop.DistributeDirection();
		}else{
			//跳过 ：其它情况
			manipulateEnable = false;
			gameLoop.DistributeDirection();
		}
	},
	
	//网络收发指令 ----------------------------------------------------
	DistributeDirection : function(){
		UnLoadManipulateEnvironment();		
		if (campaignRoom.isOnline){
			if (campaignRoom.isHost == false && gameLoop._commonid == userSet.user.id){
				//发送d： [客机]本机回合
				gameNetService.SendGameData(gameLoop._userid, 1, gameLoop._step, null, direction, null);
	
			}else if (campaignRoom.isHost && gameLoop._commonid != userSet.user.id){
				//接收d： [主机]他机回合
				
				battleLayerClickEnable = true;
				gameNetService.GetGameData(gameLoop._userid, 1, gameLoop._GetDirectionHandler);				
				return;
			}
		}
		gameLoop.GetProcessAndDirection();
	},
	
	_GetDirectionHandler : function(gamedata){
		if (gamedata.param.step != gameLoop._step || gamedata.type != 1){
			return;
		}
		
		gameNetService.StopGetGameData();
		
		direction = DeepClone(gamedata.param.direction);

		battleLayerClickEnable = false;
		gameLoop.GetProcessAndDirection();
	},
	
	//作战核算 ----------------------------------------------------
	GetProcessAndDirection : function(){
		cc.log(gameLoop._step + ".3: new direction end, judge start");
		
		if (campaignRoom.isHost)//[主机]/[单机]
			judgeBattle.Judge();
		
		gameLoop.DistributePD();
	},
	
	//网络收发“作战过程和指令” ----------------------------------------------------
	DistributePD : function(){
		if (campaignRoom.isOnline){
			if (campaignRoom.isHost){
				gameNetService.SendGameData(gameLoop._userid, 2, gameLoop._step, null, direction, wholeProcess[gameLoop._step]);
			}else{
				gameNetService.GetGameData(gameLoop._userid, 2, gameLoop._GetPDHandler);
				return;
			}
		}
		gameLoop.PlayProcess();
	},
	
	_GetPDHandler : function(gamedata){
		if (gamedata.param.step != gameLoop._step || gamedata.type != 2){
			return;
		}
		
		gameNetService.StopGetGameData();
		
		wholeProcess[gameLoop._step] = DeepClone(gamedata.param.process);
		SimulateJudge();
		
		direction = DeepClone(gamedata.param.direction);
		
		gameLoop.PlayProcess();
	},
	
	//播放作战过程 ----------------------------------------------------
	PlayProcess : function(){
		cc.log(gameLoop._step + ".4: judge end, animation start");
		processAnimation.Play();
		
		gameLoop._loopTimeoutHandle = setTimeout(
				gameLoop.EndStep, (processAnimation.duration + 3.3) * 1000);
	},
	
	//结束本回合 ----------------------------------------------------
	EndStep : function(){
		processAnimation.Stop();
		cc.log(gameLoop._step + ".5: animation end, stepEnd start");
		EndOldStep();
		
		gameLoop._loopTimeoutHandle = setTimeout(
				gameLoop.TurnStep, campaignScene.canvaslayer.showDuration * 1000);
	},
	
	//转换到下一回合 ----------------------------------------------------
	TurnStep : function(){
		cc.log(gameLoop._step + ".6: stepEnd end, turnning new step");
		TurnNewStep();
		
		gameLoop.StartStep();
	}
};

control.onDeployedClick = function(sender){
	gameLoop.DistributeDirection();
};


/* old code, for reference

control.onDeployedClick = function(sender){
	UnLoadManipulateEnvironment();
	cc.log(campaign.time_ref.current_step + ".3: manip end, judge start");
	judgeBattle.Judge();
	cc.log(campaign.time_ref.current_step + ".4: judge end, animation start");
	processAnimation.Play();
	setTimeout(function(){//time = processAnimation.duration
		cc.log(campaign.time_ref.current_step + ".5: animation end, stepEnd start");
		EndOldStep();
		cc.log(campaign.time_ref.current_step + ".6: stepEnd end, turnning new step");
		//load new step resources
		setTimeout(function(){
			TurnNewStep();
			cc.log(campaign.time_ref.current_step + ".1: stepStart start");
			StartNewStep();
			cc.log(campaign.time_ref.current_step + ".2: stepStart end, manip start");
			setTimeout(
				LoadManipulateEnvironment,
				campaignScene.canvaslayer.hideDuration * 1000);
		}, campaignScene.canvaslayer.showDuration * 1000);
	}, (processAnimation.duration + 1) * 1000);
};
*/